package performance;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

public class OutputProfilerPrinter {
	private static final String outPropertyName = "salida";
	private static final String fileOut = "File";
	private static final String systemOut = "System";
	private static final String fileProperty = "archivo";
	private OutputStream output;
	private String name;

	public OutputProfilerPrinter(final Properties properties, final String name) {
		this.initialize(properties, name);
	}

	private byte[] getBytes(final String text) {
		try {
			return text.getBytes("UTF-8");
		} catch (final UnsupportedEncodingException e) {
			throw new ProfilerException(e);
		}

	}

	private String getName() {
		return name;
	}

	private OutputStream getOutput() {
		return output;
	}

	private void initialeName(final Properties properties, final String name) {
		final String path = properties.get(OutputProfilerPrinter.fileProperty);
		this.setName(path + "/Profile(" + name + ").txt");
	}

	private void initialize(final Properties properties, final String name) {
		this.initialeName(properties, name);
		this.initializeOutput(properties);
	}

	private void initializeOutput(final Properties properties) {
		final String outputChoice = properties
				.get(OutputProfilerPrinter.outPropertyName);
		if (!outputChoice.equalsIgnoreCase(OutputProfilerPrinter.systemOut)
				&& !outputChoice
						.equalsIgnoreCase(OutputProfilerPrinter.fileOut))
			throw new ProfilerException(
					"Debe especificar la propiedad \"salida\" en 'System' o 'File'");
		if (outputChoice.equalsIgnoreCase(OutputProfilerPrinter.systemOut)) {
			this.setOutput(System.out);
		} else {
			if (outputChoice.equalsIgnoreCase(OutputProfilerPrinter.fileOut)) {
				final File file = new File(this.getName());
				try {
					this.setOutput(new FileOutputStream(file));
				} catch (final FileNotFoundException e) {
					throw new ProfilerException(e);
				}
			}
		}

	}

	public OutputProfilerPrinter print(final Long text) {
		return this.print(String.valueOf(text));
	}

	public OutputProfilerPrinter print(final String text) {
		try {
			this.getOutput().write(this.getBytes(text));
		} catch (final IOException e) {
			throw new ProfilerException("Error writing on output", e);
		}
		return this;
	}

	public OutputProfilerPrinter printLn(final Long text) {
		return this.printLn(String.valueOf(text));
	}

	public OutputProfilerPrinter printLn(final String text) {
		return this.print(text + "\n");
	}

	private void setName(final String name) {
		this.name = name;
	}

	private void setOutput(final OutputStream output) {
		this.output = output;
	}

}
